package com.xzit.rcpyxt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xzit.rcpyxt.constant.MessageCode;
import com.xzit.rcpyxt.dto.*;
import com.xzit.rcpyxt.entity.*;
import com.xzit.rcpyxt.entity.Class;
import com.xzit.rcpyxt.exceptions.CustomeException;
import com.xzit.rcpyxt.mapper.*;
import com.xzit.rcpyxt.service.CourseClassService;
import com.xzit.rcpyxt.service.SignInService;
import com.xzit.rcpyxt.utils.PageUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class CourseClassServiceImpl implements CourseClassService {

    private static final Logger logger = LogManager.getLogger(CourseClassServiceImpl.class);

    @Autowired
    private CourseClassMapper courseClassMapper;
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private ClassMapper classMapper;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private SignInMapper signInMapper;
    @Autowired
    private SignInService signInService;

    @Override
    public void saveCourseClass(SaveCourseClassReqeust courseClass) {
        int success = courseClassMapper.insertByCourseClass(courseClass);
        if (success < 1) {
            throw new CustomeException(MessageCode.SYSTEM_ERROR.getCode(), "保存课程失败！");
        }
    }

    @Override
    @Transactional
    public void updateCourseClassStatus(updateCourseClassStatusRequest courseClass) {
        CourseClass courseClass1 = courseClassMapper.selectByPrimaryKey(courseClass.getId());
        if (courseClass1 == null) {
            throw new CustomeException(MessageCode.DATA_NOT_EXISTS_ERROR.getCode(), "该课程不存在！");
        }
        Date endTime = courseClass1.getEndTime();
        if (endTime.getTime() < System.currentTimeMillis()) {
            throw new CustomeException(MessageCode.DATA_ERROR.getCode(), "该课程已超过最晚签到时间，不能开启签到！");
        }
        if (courseClass1.getSignInStatus() == 1 && courseClass.getSignInStatus() == 1) {
            throw new CustomeException(MessageCode.DATA_ERROR.getCode(), "该课程已开启签到！");
        }
        if (courseClass1.getSignInStatus() == 2) {
            throw new CustomeException(MessageCode.DATA_ERROR.getCode(), "该课程已结束！");
        }
        int success = courseClassMapper.updateByCourseClassStatus(courseClass);
        if (success < 1) {
            throw new CustomeException(MessageCode.SYSTEM_ERROR.getCode(), "修改课程签到状态失败！");
        }
        if (courseClass.getSignInStatus() == 2) {
            signInService.stopSign(courseClass1);
        }
    }

    @Override
    public PageUtil findCourseClassList(CourseClassListRequest courseClassDto) {
        int page = courseClassDto.getPage();
        int pageSize = courseClassDto.getPageSize();
        courseClassDto.setPage(page - 1);
        courseClassDto.setPageSize(page * pageSize);
        String createTime = courseClassDto.getCurrentTime();
        Date[] dayDate = null;
        if(createTime != null){
            try {
                dayDate = getDayDate(initFormat("yyyy-MM-dd").parse(createTime));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        } else {
            dayDate = getDayDate(new Date());
        }
        courseClassDto.setStartTime(dayDate[0]);
        courseClassDto.setEndTime(dayDate[1]);
        List<CourseClass> teachers = courseClassMapper.selectByCourseClassList(courseClassDto);
        List<CourseClassResponseDto> courseClassResponseDtos = new ArrayList<>();
        for (CourseClass courseClass: teachers) {
            CourseClassResponseDto courseClassResponseDto = new CourseClassResponseDto();
            BeanUtils.copyProperties(courseClass, courseClassResponseDto);
            Teacher teacher = teacherMapper.selectByTeacherUserInfo(courseClass.getTeacherId());
            if (teacher != null) {
                courseClassResponseDto.setTeacher(teacher.getName());
            }
            Class aClass = classMapper.selectByPrimaryKey(courseClass.getClassId());
            if (aClass != null) {
                courseClassResponseDto.setaClass(aClass.getName());
            }
            courseClassResponseDtos.add(courseClassResponseDto);
        }
        int totalElements = courseClassMapper.countByCourseClassList(courseClassDto);
        return new PageUtil(page, pageSize, totalElements, courseClassResponseDtos);
    }

    public static Date[] getDayDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date startDate = calendar.getTime();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 1);
        Date endDate = calendar.getTime();
        return new Date[] { startDate, endDate };
    }

    private static SimpleDateFormat initFormat(String format) {
        SimpleDateFormat mDateFormat = new SimpleDateFormat(format);
        return mDateFormat;
    }

    @Override
    public Map findByCourseDetail (int id) {
        CourseClass courseClass = courseClassMapper.selectByPrimaryKey(id);
        if (courseClass == null) {
            throw new CustomeException(MessageCode.DATA_NOT_EXISTS_ERROR);
        }
        Map data = new HashMap();
        Teacher teacher = teacherMapper.selectByTeacherUserInfo(courseClass.getTeacherId());
        Class aClass = classMapper.selectByPrimaryKey(courseClass.getClassId());
        Course course = courseMapper.selectByPrimaryKey(courseClass.getCourseId());
        data.put("id", id);
        data.put("address", courseClass.getAddress());
        data.put("signInStatus", courseClass.getSignInStatus());
        data.put("latitude", courseClass.getLatitude());
        data.put("address", courseClass.getLongitude());
        data.put("startTime", courseClass.getStartTime());
        data.put("endTime", courseClass.getEndTime());
        data.put("longitude", courseClass.getEndTime());

        data.put("teacherId", teacher != null ? teacher.getId() : 0);
        data.put("teacherName", teacher != null ? teacher.getName() : "");

        data.put("classId", aClass != null ? aClass.getId() : 0);
        data.put("className", aClass != null ? aClass.getName() : "");
        data.put("classGrade", aClass != null ? aClass.getGrade() : "");

        data.put("courseId", course != null ? course.getId() : 0);
        data.put("courseName", course != null ? course.getName() : "");

        Map map = new HashMap();
        map.put("courseClassId", id);
        map.put("status", 0);
        List<SignIn> signIns = signInMapper.selectByCourseClassStatusSignIn(map);
        data.put("signUserCount", signIns.size());
        data.put("signUserList", signIns);

        map.put("status", 1);
        List<SignIn> notSignIns = signInMapper.selectByCourseClassStatusSignIn(map);
        data.put("notSignUserCount", notSignIns.size());
        data.put("notSignUserList", notSignIns);

        return data;
    }

    @Override
    public PageUtil findStudentCourseClassList(StudentSourceClassRequest studentSourceClassRequest) {
        int page = studentSourceClassRequest.getPage();
        int pageSize = studentSourceClassRequest.getPageSize();
        studentSourceClassRequest.setPage(page - 1);
        studentSourceClassRequest.setPageSize(page * pageSize);
        String createTime = studentSourceClassRequest.getCurrentTime();
        Date[] dayDate = null;
        if(createTime != null){
            try {
                dayDate = getDayDate(initFormat("yyyy-MM-dd").parse(createTime));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        } else {
            dayDate = getDayDate(new Date());
        }
        studentSourceClassRequest.setStartTime(dayDate[0]);
        studentSourceClassRequest.setEndTime(dayDate[1]);

        Student student = studentMapper.selectByStudentUserInfo(studentSourceClassRequest.getStudengId());
        if (student == null) {
            throw new CustomeException(MessageCode.USER_NOT_EXISTS_ERROR);
        }
        studentSourceClassRequest.setClassId(student.getClassId());

        List<CourseClass> teachers = courseClassMapper.selectByUserCourseClassList(studentSourceClassRequest);
        List<StudentCourseClassDto> studentCourseClassDtos = new ArrayList<>();
        for (CourseClass courseClass : teachers) {
            StudentCourseClassDto studentCourseClassDto = new StudentCourseClassDto();
            BeanUtils.copyProperties(courseClass, studentCourseClassDto);
            SignIn signIn = new SignIn();
            signIn.setCourseClassId(courseClass.getId());
            signIn.setStudentId(studentSourceClassRequest.getStudengId());
            SignIn signIn1 = signInMapper.selectBySignIn(signIn);
            if (signIn1 != null) {
                studentCourseClassDto.setIsSignIn(signIn1.getStatus());
            } else {
                studentCourseClassDto.setIsSignIn(2);
            }
            Teacher teacher = teacherMapper.selectByTeacherUserInfo(courseClass.getTeacherId());
            if (teacher != null) {
                studentCourseClassDto.setTeacher(teacher.getName());
            }
            Class aClass = classMapper.selectByPrimaryKey(courseClass.getClassId());
            if (aClass != null) {
                studentCourseClassDto.setaClass(aClass.getName());
            }
            studentCourseClassDtos.add(studentCourseClassDto);
        }
        int totalElements = courseClassMapper.countByUserCourseClassList(studentSourceClassRequest);
        return new PageUtil(page, pageSize, totalElements, studentCourseClassDtos);
    }

    @Override
    public void timeTaskStopCourseClass () {
        List<CourseClass> courseClasses = courseClassMapper.selectByStopCourseClassList(new Date());
        courseClasses.forEach(courseClass -> {
            logger.info("timeTaskStopCourseClass " + courseClass.getId() + " " + courseClassMapper.updateByStopCourseClassStatus(courseClass.getId()));
            signInService.stopSign(courseClass);
        });
    }

    @Override
    public PageUtil findCourseClassSignList(CourseClassListRequest courseClassDto) {
        int page = courseClassDto.getPage();
        int pageSize = courseClassDto.getPageSize();
        courseClassDto.setPage(page - 1);
        courseClassDto.setPageSize(page * pageSize);
        String createTime = courseClassDto.getCurrentTime();
        Date[] dayDate = null;
        if(createTime != null){
            try {
                dayDate = getDayDate(initFormat("yyyy-MM-dd").parse(createTime));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        } else {
            dayDate = getDayDate(new Date());
        }
        courseClassDto.setStartTime(dayDate[0]);
        courseClassDto.setEndTime(dayDate[1]);
        List<CourseClass> teachers = courseClassMapper.selectByCourseClassList(courseClassDto);
        List<Map> courseClassResponseDtos = new ArrayList<>();
        for (CourseClass courseClass: teachers) {
            courseClassResponseDtos.add(findByCourseDetail(courseClass.getId()));
        }
        int totalElements = courseClassMapper.countByCourseClassList(courseClassDto);
        return new PageUtil(page, pageSize, totalElements, courseClassResponseDtos);
    }

}